﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for Logging
/// </summary>
public static class Logging
{
    /// <summary>
    /// Event available to log
    /// </summary>
    public enum LogEvent
    {
        // project event
        AddProject,
        UpdateProjectInfo,
        SetProjectStatus,
        AssignUserToProject, // also user event
        UnassignUserFromProject, // also user event

        // bug event
        AddBug,
        UpdateBugInfo,
        SetBugStatus,
        AssignUserToBug, // also user event
        UnassignUserFromBug, // also user event

        // user event
        CreateUser,
        UpdateUser,
        EnableUser
    }

    /// <summary>
    /// Log an event related to a Project
    /// </summary>
    /// <param name="logEvent">must be an event related to project</param>
    /// <param name="project">project to log</param>
    /// <param name="byUsername">username of user making the event</param>
    /// <param name="toUsername">targetted usernam, can be null with some project events</param>
    public static void AddLog(LogEvent logEvent, Project project, string byUsername, string toUsername)
    {
        try
        {
            // check if Log Event is a Project event
            if (logEvent != LogEvent.AddProject && logEvent != LogEvent.UpdateProjectInfo
                && logEvent != LogEvent.SetProjectStatus && logEvent != LogEvent.AssignUserToProject
                && logEvent != LogEvent.UnassignUserFromProject)
            {
                return;
                throw new Exception("LogThis was called to log an event related to Project but Log Event does not match");
            }

            // create a new project log
            Log log = new Log();
            log.LogEvent = (int)logEvent;
            log.ProjectId = project.ProjectId;
            log.Time = DateTime.Now;
            log.ByUser = byUsername;

            // if a second username is assigned
            if (log.ToUser != null) log.ToUser = toUsername;

            // if this event changes the project's description and custom message
            if (logEvent == LogEvent.AddProject || logEvent == LogEvent.UpdateProjectInfo)
                log.CustomMessage = "<ul class='report-description'><li>Description: " + project.Description +
                                    "</li><li>Custom Message: " + project.CustomMessage + "</li></ul>";

            // if this event changes the project's status
            else if (logEvent == LogEvent.SetProjectStatus)
                if (project.IsActive)
                    log.CustomMessage = "opened";
                else
                    log.CustomMessage = "closed";

            // save the new log to database
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.InsertOnSubmit(log);
            ApplicationGlobalVariables.KillDaBugsDatabase.SubmitChanges();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Log an event related to a Bug
    /// </summary>
    /// <param name="logEvent">must be an event related to bug</param>
    /// <param name="bug">bug to log</param>
    /// <param name="byUsername">user making the event</param>
    /// <param name="toUsername">targetted user, can be null with some bug events</param>
    public static void AddLog(LogEvent logEvent, Bug bug, string byUsername, string toUsername)
    {
        try
        {
            // check if Log Event is a Bug event
            if (logEvent != LogEvent.AddBug && logEvent != LogEvent.SetBugStatus
                && logEvent != LogEvent.UpdateBugInfo && logEvent != LogEvent.AssignUserToBug
                && logEvent != LogEvent.UnassignUserFromBug)
            {
                return;
                throw new Exception("LogThis was called to log an event related to Bug but Log Event does not match");
            }

            // create a new bug log
            Log log = new Log();
            log.LogEvent = (int)logEvent;
            log.BugId = bug.BugId;
            log.Time = DateTime.Now;
            log.ByUser = byUsername;

            // if a second username is assigned
            if (log.ToUser != null) log.ToUser = toUsername;

            // if this event changes the bug's info
            if (logEvent == LogEvent.AddBug || logEvent == LogEvent.UpdateBugInfo)
            {
                // save the bug info at this time of logging
                log.CustomMessage = "<ul class='report-description'><li>Summary: " + bug.Summary +
                                    "</li><li>Description: " + bug.Description +
                                    "</li><li>Priority: " + bug.Priority +
                                    "</li><li>Reproducability: " + bug.Reproducability +
                                    "</li><li>Severity: " + bug.Severity + "</li></ul>";

                // get the time from this bug's properties for consistency
                log.Time = bug.LastUpdatedDate;
            }
            else if (logEvent == LogEvent.SetBugStatus)
                log.CustomMessage = EnumUtility.GetEnumNiceName((BugManagement.Status)bug.Status);

            // save the new log to database
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.InsertOnSubmit(log);
            ApplicationGlobalVariables.KillDaBugsDatabase.SubmitChanges();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Log an event related to a User
    /// </summary>
    /// <param name="logEvent">must be an event related to User</param>
    /// <param name="user">User making the log</param>
    public static void AddLog(LogEvent logEvent, User user)
    {
        try
        {
            // check if Log Event is a User event
            if (logEvent != LogEvent.CreateUser && logEvent != LogEvent.UpdateUser && logEvent != LogEvent.EnableUser)
            {
                return;
                throw new Exception("LogThis was called to log an event related to User but Log Event does not match");
            }

            // create a new user log
            Log log = new Log();
            log.LogEvent = (int)logEvent;
            log.ByUser = user.Username;
            log.Time = DateTime.Now;

            if (logEvent == LogEvent.EnableUser)
                if (user.IsActive == true)
                    log.CustomMessage = "enabled";
                else
                    log.CustomMessage = "disabled";
            else
                // record changes made to user profile
                log.CustomMessage = "<ul class='report-description'><li>Full name: " + user.Fullname +
                                    "</li><li>Email: " + user.Email +
                                    "</li><li>Organization: " + user.Organization +
                                    "</li><li>Custom Information: " + user.CustomInfo + "</li></ul>";

            // save the new log to database
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.InsertOnSubmit(log);
            ApplicationGlobalVariables.KillDaBugsDatabase.SubmitChanges();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// Log CreateUser Event of a user
    /// </summary>
    /// <param name="username">username of user making the log</param>
    public static void AddLog(string username)
    {
        try
        {
            // create a new user log
            Log log = new Log();
            log.LogEvent = (int)LogEvent.CreateUser;
            log.ByUser = username;
            log.Time = DateTime.Now;

            // save the new log to database
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.InsertOnSubmit(log);
            ApplicationGlobalVariables.KillDaBugsDatabase.SubmitChanges();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// gets a list of logs related to a user
    /// </summary>
    /// <param name="username">username of the user</param>
    /// <returns>list of logs related to the user</returns>
    public static List<Log> GetLogUser(string username)
    {
        return (List<Log>)ApplicationGlobalVariables.KillDaBugsDatabase.Logs.Where(i => i.ByUser == username);
    }

    /// <summary>
    /// gets a list of logs related to a project
    /// </summary>
    /// <param name="projectId">ID of the project</param>
    /// <returns>list of logs related to the project</returns>
    public static List<Log> GetLogProject(int projectId)
    {
        return (List<Log>)ApplicationGlobalVariables.KillDaBugsDatabase.Logs.Where(i => i.ProjectId == projectId);
    }

    /// <summary>
    /// gets a list of logs related to a bug
    /// </summary>
    /// <param name="bugId">ID of the bug</param>
    /// <returns>list of logs related to the bug</returns>
    public static IQueryable<Log> GetLogBug(int bugId)
    {
        return ApplicationGlobalVariables.KillDaBugsDatabase.Logs.Where(i => i.BugId == bugId);
    }

    /// <summary>
    /// clear all logs related to a user
    /// </summary>
    /// <param name="username">username of the user</param>
    /// <returns>true if log cleared, otherwise false</returns>
    public static bool ClearLogUser(string username)
    {
        try
        {
            var logs = from log in ApplicationGlobalVariables.KillDaBugsDatabase.Logs
                       where log.ByUser == username || log.ToUser == username
                       select log;
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.DeleteAllOnSubmit(logs);
            return true;
        }
        catch (Exception ex)
        {
            return false;
            throw ex;
        }
    }

    /// <summary>
    /// clear all logs related to a project
    /// </summary>
    /// <param name="projectId">project ID of the project</param>
    /// <returns>true if log cleared, otherwise false</returns>
    public static bool ClearLogProject(int projectId)
    {
        try
        {
            var logs = from log in ApplicationGlobalVariables.KillDaBugsDatabase.Logs
                       where log.ProjectId == projectId
                       select log;
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.DeleteAllOnSubmit(logs);
            return true;
        }
        catch (Exception ex)
        {
            return false;
            throw ex;
        }
    }

    /// <summary>
    /// clear all logs related to a bug
    /// </summary>
    /// <param name="username">bug ID of the bug</param>
    /// <returns>true if log cleared, otherwise false</returns>
    public static bool ClearLogBug(int bugId)
    {
        try
        {
            var logs = from log in ApplicationGlobalVariables.KillDaBugsDatabase.Logs
                       where log.BugId == bugId
                       select log;
            ApplicationGlobalVariables.KillDaBugsDatabase.Logs.DeleteAllOnSubmit(logs);

            return true;
        }
        catch (Exception ex)
        {
            return false;
            throw ex;
        }
    }
}